package by.dvrudenko.avtobaza.dataaccess.impl;

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.commons.lang3.Validate;
import org.hibernate.jpa.criteria.OrderImpl;
import org.springframework.stereotype.Repository;

import by.dvrudenko.avtobaza.dataaccess.ResponsesDao;
import by.dvrudenko.avtobaza.datamodel.Responses;
import by.dvrudenko.avtobaza.datamodel.Responses_;

@Repository
public class ResponsesDaoImpl extends AbstractDaoImpl<Long, Responses>
		implements ResponsesDao {

	public ResponsesDaoImpl() {
		super(Responses.class);
	}

	@Override
	// возвращать 5 отзавов по порядку начиная со случайного отзыва
	public List<Responses> getRandomResponses(Integer count) {
		Validate.notNull(count, "count - attributes can't be null");
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();
		CriteriaQuery<Responses> criteria = cBuilder
				.createQuery(Responses.class);
		Root<Responses> root = criteria.from(Responses.class);

		criteria.select(root);
		root.fetch(Responses_.user);
		criteria.distinct(true);

		long responsesCount = getCount();
		int numberFirstResponses = randInt(0, (int) Math.abs(responsesCount - count));
		// если отзывов в базе будет меньше заданного кол-ва
		// то вывести все отзывы начиная с 0
		if (responsesCount < count) {
			numberFirstResponses = 0;
			count = (int) responsesCount;
		}

		TypedQuery<Responses> query = getEm().createQuery(criteria);
		query.setFirstResult(numberFirstResponses).setMaxResults(count);
		return query.getResultList();

	}

	@Override
	public Long getCount() {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Long> criteria = cBuilder.createQuery(Long.class);
		Root<Responses> root = criteria.from(Responses.class);

		criteria.select(cBuilder.count(root));

		TypedQuery<Long> query = getEm().createQuery(criteria);
		return query.getSingleResult();
	}

	@Override
	public List<Responses> getAllResponses(SingularAttribute<Responses, ?> attr,
			boolean ascending, int startRecord, int pageSize) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Responses> criteria = cBuilder.createQuery(Responses.class);
		Root<Responses> root = criteria.from(Responses.class);

		criteria.select(root);
		root.fetch(Responses_.user);
		criteria.distinct(true);
		criteria.orderBy(new OrderImpl(root.get(attr), ascending));

		TypedQuery<Responses> query = getEm().createQuery(criteria);
		query.setFirstResult(startRecord);
		query.setMaxResults(pageSize);

		List<Responses> results = query.getResultList();
		return results;
	}
}
